package com.example.vpn_demo.proxy

import android.util.Log
import java.io.File
import java.net.ServerSocket
import java.security.cert.X509Certificate
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.net.Socket

class BrowserMobProxyManager {
    companion object {
        private const val TAG = "BrowserMobProxyManager"
        const val PROXY_PORT = 8888
    }

    private var serverSocket: ServerSocket? = null
    private var executor: ExecutorService? = null
    private var isRunning = false

    fun start(rootCert: X509Certificate, certFile: File) {
        if (isRunning) return

        try {
            serverSocket = ServerSocket(PROXY_PORT)
            executor = Executors.newCachedThreadPool()
            isRunning = true

            executor?.execute {
                while (isRunning) {
                    try {
                        val clientSocket = serverSocket?.accept() ?: continue
                        executor?.execute {
                            handleConnection(clientSocket)
                        }
                    } catch (e: Exception) {
                        if (isRunning) {
                            Log.e(TAG, "接受连接失败", e)
                        }
                    }
                }
            }

            Log.i(TAG, "代理服务器已启动，端口: $PROXY_PORT")
        } catch (e: Exception) {
            Log.e(TAG, "启动代理服务器失败", e)
            throw e
        }
    }

    private fun handleConnection(clientSocket: Socket) {
        try {
            val input = clientSocket.getInputStream().bufferedReader()
            val output = clientSocket.getOutputStream()

            // 读取请求行
            val requestLine = input.readLine() ?: return
            val (method, uri, version) = requestLine.split(" ")
            
            Log.i(TAG, """
                ┌──────────── 请求 ────────────
                │ $requestLine
                └────────────────────────────────────
            """.trimIndent())

            // 读取请求头
            val headers = mutableMapOf<String, String>()
            var line: String?
            while (input.readLine().also { line = it } != null && line!!.isNotEmpty()) {
                val parts = line!!.split(": ", limit = 2)
                if (parts.size == 2) {
                    headers[parts[0]] = parts[1]
                }
            }

            Log.i(TAG, """
                ┌──────────── 请求头 ────────────
                ${headers.entries.joinToString("\n") { "│ ${it.key}: ${it.value}" }}
                └────────────────────────────────────
            """.trimIndent())

            // 解析目标地址
            val host = headers["Host"] ?: return
            val (targetHost, targetPort) = if (host.contains(":")) {
                host.split(":")
            } else {
                listOf(host, if (uri.startsWith("https")) "443" else "80")
            }

            // 连接目标服务器
            val targetSocket = Socket(targetHost, targetPort.toInt())
            val targetInput = targetSocket.getInputStream().bufferedReader()
            val targetOutput = targetSocket.getOutputStream()

            // 如果是 HTTPS 请求，发送 CONNECT 响应
            if (method == "CONNECT") {
                output.write("HTTP/1.1 200 Connection Established\r\n\r\n".toByteArray())
                output.flush()
                
                // 启动双向转发
                executor?.execute {
                    try {
                        val buffer = ByteArray(8192)
                        var bytesRead: Int
                        while (clientSocket.getInputStream().read(buffer).also { bytesRead = it } != -1) {
                            targetSocket.getOutputStream().write(buffer, 0, bytesRead)
                            targetSocket.getOutputStream().flush()
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "客户端到服务器转发失败", e)
                    }
                }

                executor?.execute {
                    try {
                        val buffer = ByteArray(8192)
                        var bytesRead: Int
                        while (targetSocket.getInputStream().read(buffer).also { bytesRead = it } != -1) {
                            clientSocket.getOutputStream().write(buffer, 0, bytesRead)
                            clientSocket.getOutputStream().flush()
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "服务器到客户端转发失败", e)
                    }
                }
            } else {
                // 转发 HTTP 请求
                targetOutput.write("$requestLine\r\n".toByteArray())
                for ((key, value) in headers) {
                    targetOutput.write("$key: $value\r\n".toByteArray())
                }
                targetOutput.write("\r\n".toByteArray())

                // 如果有请求体，转发请求体
                if (headers.containsKey("Content-Length")) {
                    val contentLength = headers["Content-Length"]?.toInt() ?: 0
                    val body = CharArray(contentLength)
                    input.read(body)
                    targetOutput.write(String(body).toByteArray())
                }
                targetOutput.flush()

                // 读取并转发响应
                val buffer = ByteArray(8192)
                var bytesRead: Int
                while (targetSocket.getInputStream().read(buffer).also { bytesRead = it } != -1) {
                    output.write(buffer, 0, bytesRead)
                    output.flush()
                }
            }

        } catch (e: Exception) {
            Log.e(TAG, "处理请求失败", e)
        } finally {
            try {
                clientSocket.close()
            } catch (e: Exception) {
                Log.e(TAG, "关闭客户端连接失败", e)
            }
        }
    }

    fun stop() {
        try {
            isRunning = false
            serverSocket?.close()
            executor?.shutdown()
            serverSocket = null
            executor = null
            Log.i(TAG, "代理服务器已停止")
        } catch (e: Exception) {
            Log.e(TAG, "停止代理服务器失败", e)
        }
    }

    fun isRunning() = isRunning
} 